import JsCookie from 'js-cookie'
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { updateThemeConfig } from '@/utils/theme'
import { IGetCode, IThunkState, NewThemeConfig } from '@/global/type'
import {
  getEmailCode,
  getMenuInfoById,
  getPersonalInfo,
  getPhoneCode,
  getPublicKey,
  reqSecondAuth
} from '@/service/module/app'
import {
  CacheType,
  IS_NEED_SECOND_AUTH,
  PUBLIC_KEY,
  Status,
  ThemeMode,
  VerifyType
} from '@/global/constant'
import { localCache } from '@/utils/cache'
import { decryptData } from '@/utils/encrypt'
import { initWebsocketAction } from '@/store/module/websocket'

interface IState {
  themeConfig: NewThemeConfig
  isModeChecked: boolean
  publicKey: string
  privateKey: string
  isCounting: boolean
  userInfo: any
  menuCodeList: string[]
  menuList: any[]
}

const localThemeConfig = localCache.getCache(CacheType.THEME_CONFIG)
const themeConfig =
  localThemeConfig ??
  updateThemeConfig(
    {
      colorPrimary: '#1677FF',
      mode: ThemeMode.Day
    },
    {}
  )
// 如果本地没有主题配置，初始化一套配置
if (!localThemeConfig) localCache.setCache(CacheType.THEME_CONFIG, themeConfig)

const initialState: IState = {
  themeConfig,
  isModeChecked: localThemeConfig?.algorithm !== ThemeMode.Day,
  publicKey: '',
  privateKey:
    'MIICWgIBAAKBgG0ZdSVQahU6blq3eAUdvGwH2jjKj7l1ZEQUexTFTt3Hg3LsumBVPFtMptgMQzLhwAzp0NiZHHd9DuGDT/jOq4+vbWsvCZQeo+RqK2qi49y8duoOYlUwHHYAgqMlguanR+0M4tXDOO+uExAbMYROQmRxR5JWlUbhBlqyvPKKLFvlAgMBAAECgYA12fQN+BR06AOiuZ7/f38LIBEiKTIqS/yy8h0S0pWsORf0OU+Bz3DcbAiK6fqdefsPJLaWw3TeshcPT37BBFqADA5aOCp5rsR5JJVg9FD/ieZ8JmL28PPwXwQ4uwGabuslk5F3p/uH1APPi8Zq0Uh+XOX6qQ7zayrHtSln10ImgQJBAKexfNQtczc3dd+WuoiebCAEW+kAtiBooYdUSBq5fCwwxLdqwUTwLfFN3EUN1L+iklGTtg0V8+gpTieqo1N/HCECQQCmjQI0ziuDq5Vx0JMP0VDGb/WMHbAHaOygVVUjAAJPC9I8M0bSINd0xkAlQsIV3+6yc4ymvVL4n96GjUnFiOdFAkBCMKBg73+mr9Fq64e9HSr4iD/u/ETnDeWUEQRU6BnHJ4i+DPk0SMkZke37o7Xx3i163Z7iE2Quov8iUQwejPGBAkA+xAFC2Te45V7qh4oEegOQ5PyKk12VTUtvmPj+ubAlDfVqzoAwDERmM5hU8nWmPL/97GHjLJIqNEVuO6zDjrZpAkABobpOY2cge7G7UWsWzI40vJemdfpyFQ+mM/qiMPGzM/9xwczjuRa7TD2ulh5aKI5BZw35ggrn23IJECrUI92u',
  isCounting: false,
  userInfo: {},
  // 用户权限字段
  menuCodeList: [],
  // 用户菜单列表
  menuList: []
}

// 手机和邮件验证都用这个接口
export const fetchVerifyCodeAction = createAsyncThunk<Status, IGetCode>(
  'fetch/verifyCode',
  (config) => {
    const fn = VerifyType.Phone === config.type ? getPhoneCode : getEmailCode
    return fn(config.data)
      .then((res) => {
        console.log(res)
        return Status.SUCCESS
      })
      .catch((err) => Status.FAIL)
  }
)

// 获取rsa公钥
export const fetchPublicKeyAction = createAsyncThunk(
  'fetch/publicKey',
  async (_, { dispatch }) => {
    const res = await getPublicKey()
    localCache.setCache(PUBLIC_KEY, res.data)
    dispatch(changePublicKeyAction(res.data))
    return res.data
  }
)

// 初始化用户数据：包括基本信息、菜单数据
export const fetchInitialUserData = createAsyncThunk<void, void, IThunkState>(
  'fetch/initialUserData',
  async (_, { getState, dispatch }) => {
    // 获取用户信息
    const userinfo = await getPersonalInfo()
    console.log('用户信息', userinfo)
    // 用私钥去解密信息
    const privateKey = getState().app.privateKey
    const info = decryptData(privateKey, userinfo.data)
    if (info) {
      dispatch(changePersonalInfoAction(info))
      localCache.setCache(CacheType.USER_INFO, info)
    }
    // 获取用户菜单
    const menuinfo = await getMenuInfoById()
    console.log('用户菜单', menuinfo)
    dispatch(changeMenuInfoAction(menuinfo.data))
    const { menuCodeList, menuList } = menuinfo.data
    localCache.setCache(CacheType.MENU_LIST, menuList)
    localCache.setCache(CacheType.MENU_CODE_LIST, menuCodeList)
    // 初始化websocket
    dispatch(initWebsocketAction(''))
    return
  }
)
// 清除核心的本地信息
export const fetchClearLocalCoreData = createAsyncThunk(
  'fetch/clearLocalCoreData',
  () => {
    const removableTypes = [
      CacheType.TOKEN,
      CacheType.USER_INFO,
      CacheType.MENU_CODE_LIST,
      CacheType.MENU_LIST
    ]
    removableTypes.forEach((type) => {
      localCache.removeCache(type)
    })
  }
)

// 二级认证
export const fetchSecondAuthAction = createAsyncThunk(
  'fetch/secondAuth',
  async (data: any) => {
    await reqSecondAuth(data)
    // 利用js-cookie插件设置一个标识,如果过期了就获取不到值，那么就要重新认证
    JsCookie.set(IS_NEED_SECOND_AUTH, 'no', { expires: 2 / 1450 })
    return true
  }
)

const appSlice = createSlice({
  name: 'app',
  initialState,
  reducers: {
    // 修改主题色以及更换模式
    changeThemeConfigAction(state, { payload }) {
      state.themeConfig = payload
    },
    // 修改主题色以及更换模式
    changeModeCheckedAction(state, { payload }) {
      state.isModeChecked = payload
    },
    // 保存rsa公钥
    changePublicKeyAction(state, { payload }) {
      state.publicKey = payload
    },
    // 修改发送验证码的状态
    changeIsCountingAction(state, { payload }) {
      state.isCounting = payload
    },
    // 保存用户信息
    changePersonalInfoAction(state, { payload }) {
      state.userInfo = payload
    },
    // 保存用户菜单数据: 包括 权限字段和菜单列表
    changeMenuInfoAction(state, { payload }) {
      state.menuList = payload.menuList
      state.menuCodeList = payload.menuCodeList
    }
  }
})

export const {
  changeThemeConfigAction,
  changeModeCheckedAction,
  changePublicKeyAction,
  changeIsCountingAction,
  changePersonalInfoAction,
  changeMenuInfoAction
} = appSlice.actions
export default appSlice.reducer
